﻿using System;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;

namespace TMT_CMS.BL.Excel.AttributeUtility
{
    public static class AttributeHelper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static T ConvertFromDR<T>(DataRow dr) where T : new()
        {
            return ConvertFromDR<T>(dr, false);
        }

        /// <summary>
        /// We will build the entity from data row according to its data attribute 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <param name="isFromExcel"></param>
        /// <returns></returns>
        public static T ConvertFromDR<T>(DataRow dr, bool isFromExcel) where T : new()
        {
            T entity = new T();

            // get all property from the type of T
            Type type = typeof(T);
            PropertyInfo[] properties = type.GetProperties();
            if (properties != null && properties.Length != 0)
            {
                foreach (PropertyInfo property in properties)
                {
                    DataAttribute dataAttr = Attribute.GetCustomAttribute(property, typeof(DataAttribute)) as DataAttribute;
                    if (dataAttr != null)
                    {
                        if (!isFromExcel)
                        {
                            #region get value from database row
                            string columnName = dataAttr.DataName;
                            if (dr.Table.Columns.Contains(columnName))
                            {
                                object obj = dr[columnName];
                                if (obj != DBNull.Value)
                                {
                                    switch (dataAttr.DataType)
                                    {
                                        case DataType.DateTime:
                                            DateTime valueDT = Convert.ToDateTime(obj);
                                            property.SetValue(entity, valueDT, null);
                                            break;
                                        case DataType.Int:
                                            int valueInt = Convert.ToInt32(obj);
                                            property.SetValue(entity, valueInt, null);
                                            break;
                                        case DataType.Long:
                                            long valueLong = Convert.ToInt64(obj);
                                            property.SetValue(entity, valueLong, null);
                                            break;
                                        case DataType.ShortInt:
                                            short valueShort = Convert.ToInt16(obj);
                                            property.SetValue(entity, valueShort, null);
                                            break;
                                        case DataType.String:
                                            String valueStr = Convert.ToString(obj);
                                            property.SetValue(entity, valueStr, null);
                                            break;
                                        case DataType.Bool:
                                            bool valueBool = Convert.ToBoolean(obj);
                                            property.SetValue(entity, valueBool, null);
                                            break;
                                        case DataType.Float:
                                            float valueFloat = Convert.ToSingle(obj);
                                            property.SetValue(entity, valueFloat, null);
                                            break;
                                    }
                                }
                            }
                            #endregion
                        }
                        else
                        {
                            string excelColumnName = dataAttr.ExcelColumnName;
                            if (dr.Table.Columns.Contains(excelColumnName))
                            {
                                object obj = dr[excelColumnName];
                                if (obj != DBNull.Value)
                                {
                                    try
                                    {
                                        switch (dataAttr.DataType)
                                        {
                                            case DataType.DateTime:
                                                DateTime valueDT = Convert.ToDateTime(obj);
                                                property.SetValue(entity, valueDT, null);
                                                break;
                                            case DataType.Int:
                                                int valueInt = Convert.ToInt32(obj);
                                                property.SetValue(entity, valueInt, null);
                                                break;
                                            case DataType.Long:
                                                long valueLong = Convert.ToInt64(obj);
                                                property.SetValue(entity, valueLong, null);
                                                break;
                                            case DataType.ShortInt:
                                                short valueShort = Convert.ToInt16(obj);
                                                property.SetValue(entity, valueShort, null);
                                                break;
                                            case DataType.String:
                                                String valueStr = Convert.ToString(obj);
                                                valueStr = valueStr.Replace(" ", " ");
                                                property.SetValue(entity, valueStr, null);
                                                break;
                                            case DataType.Bool:
                                                string str = obj.ToString();
                                                bool valueBool = false;
                                                if (str == "是")
                                                {
                                                    valueBool = true;
                                                }
                                                else if (str == "否")
                                                {
                                                    valueBool = false;
                                                }
                                                else
                                                {
                                                    valueBool = Convert.ToBoolean(obj);
                                                }
                                                property.SetValue(entity, valueBool, null);
                                                break;
                                            case DataType.Float:
                                                float valueFloat = Convert.ToSingle(obj);
                                                property.SetValue(entity, valueFloat, null);
                                                break;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        throw ex;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return entity;
        }

        public static string GetExcelColumnName<T>(string propertyName)
        {
            Type type = typeof(T);
            List<PropertyInfo> properties = new List<PropertyInfo>(type.GetProperties());
            PropertyInfo property = properties.FirstOrDefault(p => p.Name == propertyName);

            string retValue = string.Empty;
            if (property != null)
            {
                DataAttribute dataAttr = Attribute.GetCustomAttribute(property, typeof(DataAttribute)) as DataAttribute;
                if (dataAttr != null)
                {
                    retValue = dataAttr.ExcelColumnName;
                }
            }
            return retValue;
        }
    }
}